//
// Created by ych on 2/15/24.
//

#ifndef MATINTERPRETER_PARSER_H
#define MATINTERPRETER_PARSER_H

#include "lexer.h"
#include "symbols.h"
#include "../common/ych_error.h"
#include "../common/ych_stack.h"
#include "../vm/memory.h"

#define PARSER_ERROR 0
#define PARSER_OK 1
#define PARSER_END 2
#define FIRST_NT LAST_TK_
typedef enum NT_ {
    NT_S = FIRST_NT,
    NT_DS, NT_DL, NT_DV, NT_DA, NT_DF,
    NT_MAT_V_IN, NT_MAT_V_IN_IN, NT_MAT_V_1_F, NT_MAT_V_2_F,
    NT_FS, NT_FS_PARAM_LIST, NT_FS_R, NT_FS_PARAM_LIST_F, NT_S_LIST,
    NT_RS, NT_R_F,
    NT_ES,
    NT_E10, NT_E10_F, NT_E9, NT_E9_F, NT_E8, NT_E8_F, NT_E7, NT_E6, NT_E6_F,
    NT_E5, NT_E5_F, NT_E4, NT_E4_F, NT_E3, NT_E3_F, NT_E2, NT_E1, NT_E1_F,
    NT_F, NT_F_F, NT_F_F_F, NT_F_PARAM_LIST, NT_F_PARAM_LIST_F, NT_F_CONST,
    NT_IS, NT_IS_ELSE,
    NT_WS,
    NT_BS,
    NT_CS,
    NT_ARRAY, NT_ARRAY_F, NT_ARRAY_LENGTH,
    LAST_NT_
} NT_;
typedef struct LoopEvn {
    struct LoopEvn *pre;
} LoopEvn;
typedef struct FuncState {
    struct FuncState *pre;
    Uint func_p;
    int count;
    int func_params;
    int var_nums;
} FuncState;
typedef struct MatState {
    int row, col;
    int t_col;
    Uint i_p;
} MatState;
typedef struct CState {
    VMMemory *memory;
    Uint vm_mem_p;
    Uint vm_i_p;
    Uint vm_i_f_p;
    Uint vm_int_const_p;
    Uint vm_float_const_p;
    Uint vm_string_const_p;
    Uint vm_c_func_p;
    Uint func_mem_p;
    Uint array_offset;
    Uint array_start;
    Uint array_length;
    int is_declare_array_length;
    int is_declare_func;
} CState;
typedef struct Recode {
    Uint vm_mem_p;
    Uint vm_i_p;
    Uint vm_i_f_p;
} Recode;
typedef struct VarNode {
    struct VarNode *pre;
    char *var_string;
} *VarList, VarNode;

typedef struct FuncNode {
    struct FuncNode *pre;
    char *func_string;
} *FuncList, FuncNode;
typedef struct YState YState;
typedef struct YParser {
    YState *y_state;
    Lexer *lexer;
    Token current_token;
    SYNStack syn_stack;
    char *temp_string;

    CState c_state;
    SEMStack sem_stack;
    SEMStack sem_stack_if;
    MatState mat_state;
    FuncState *func_state;
    FuncInfo *func_info;
    LoopEvn *loop_evn;
    Symbols symbols;
    Recode recode;
    VarList var_list;
    FuncList func_list;

} Parser;

void initParser(Parser *parser, YState *y_state);

void freeParser(Parser *parser);

void recordSemantics(Parser *parser);

void rollbackSemantics(Parser *parser);

void analyzeParser(Parser *parser);

int analyzeStatementParser(Parser *parser);

void stageVar(Parser *parser);

void stageFunc(Parser *parser);

void clearStage(Parser *parser);

void rollbackSymbols(Parser *parser);

void throwParser(Parser *parser);

static int deduce(T x, T w, SYNStack *stack);

#endif //MATINTERPRETER_PARSER_H
